/**
 * @description:
 * @file: util.ts
 * @author: Evan
 * @date: 2025.04.08 09:23:16
 * @week: 周二
 * @version: V
 * */

interface ResponseBody {
  code?: number | boolean
  message?: string
  data?: any
  [key: string]: any
}

export const builder = (data: any, message?: string, code?: number) => {
  let responseBody: ResponseBody | string | any[] = {}
  if (typeof data === 'string' || data instanceof Array) {
    responseBody = data
  } else {
    message != void 0 && (responseBody.message = message)
    code != void 0 && (responseBody.code = code)
    if (typeof data == 'object') {
      Object.keys(data).forEach(key => {
        responseBody instanceof Object &&
          !(responseBody instanceof Array) &&
          (responseBody[key] = data[key])
      })
    }
  }
  return responseBody
}

import dayjs from 'dayjs'

// 获取一年中的第几周
const getWeek = (date: Date) => {
  // 时间戳
  const tsp = date.getTime()
  const wDate = new Date(tsp)
  // 设置年初
  wDate.setMonth(0)
  wDate.setDate(1)
  // 周开始位置 1-7 对应星期
  let weekStart = dayjs.en.weekStart || 7
  // 获取周几
  const ww = wDate.getDay()
  const dif = ww - weekStart
  const oneDay = 24 * 3600 * 1000
  // 年开始时间戳
  const yearStartTsp = wDate.getTime() - dif * oneDay
  const wk = Math.ceil((tsp - yearStartTsp) / (7 * oneDay)) + 1
  return wk
}

export const formatDate = (tsp?: number | Date, fmt: string = 'yyyy-MM-dd hh:mm:ss'): string => {
  let date: Date
  if (typeof tsp == 'number') {
    if (tsp == 0) return ''
    date = new Date(tsp)
  } else if (tsp instanceof Date) date = tsp
  else date = new Date()
  let o: AnyObject = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'w+': getWeek(date), // 第几周
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substring(4 - RegExp.$1.length))
  }
  for (let k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substring(('' + o[k]).length)
      )
    }
  }
  return fmt
}

const hour = 60 * 60 * 1000
const TspObj = {
  hour: hour,
  day: 24 * hour,
  week: 7 * 24 * hour,
  month: 30 * 24 * hour,
  quarter: 3 * 30 * 24 * hour,
  year: 4 * 3 * 30 * 24 * hour
}

type SpeedKeys = keyof typeof TspObj

const getSpeed = (type: SpeedKeys, tsp: number) => {
  const date = new Date(tsp)
  const mLen = getMonthLen(date.getMonth() + 1, date.getFullYear())
  TspObj.month = mLen * 24 * hour
  return TspObj[type]
}

export const getDateList = (start: number, end: number, type: SpeedKeys) => {
  let speed = getSpeed(type, start)
  const data: number[] = []
  let current = start
  while (current <= end) {
    data.push(current)
    current += speed
    speed = getSpeed(type, start)
  }
  return data
}

/**
 * 获取月份天数
 * @param { number } month 月份  默认：当前月份
 * @param { number } year 年份  默认：当前年份
 * @return { number } 月份天数
 * @example
 * getMonthLen( 2, 2022 )
 */
export const getMonthLen = (month?: number, year?: number): number => {
  const now = new Date()
  let len = 0
  !month && (month = now.getMonth() + 1)
  !year && (year = now.getFullYear())
  if (month == 2) {
    len = year % 4 == 0 ? 29 : 28
  } else if (
    month == 1 ||
    month == 3 ||
    month == 5 ||
    month == 7 ||
    month == 8 ||
    month == 10 ||
    month == 12
  ) {
    len = 31
  } else {
    len = 30
  }
  return len
}

interface StartAndEndTsp {
  start: number
  end: number
}

/**
 * 获取日期(一天/月/年)的开始和结束时间戳
 * @param { number } tsp 获取日期的时间戳
 * @param { number } type 获取类型 1-日 2-月 3-年 默认：1
 * @param { number } day 天数/月数/年数 可负值 默认：0
 * @return { StartAndEndTsp } 起点终点时间戳
 * @example
 * getDateOriginAndEnd( 0, 2 )
 */
export const getDateOriginAndEnd = (
  tsp?: number,
  type: number = 1,
  day: number = 0
): StartAndEndTsp => {
  let date = tsp ? new Date(tsp) : new Date()
  if (type == 1) {
    date.setDate(date.getDate() + day)
  }

  if (type == 2) {
    date.setDate(1)
    date.setMonth(date.getMonth() + day)
  } else if (type == 3) {
    date.setMonth(0)
    date.setDate(1)
    date.setFullYear(date.getFullYear() + day)
  }

  // 开始时间
  date.setHours(0)
  date.setMinutes(0)
  date.setSeconds(0)
  date.setMilliseconds(0)
  let start = date.getTime()

  const currentDate = new Date()
  if (type == 2) {
    let len = getMonthLen(date.getMonth() + 1, date.getFullYear())
    // 判断是否为当月
    if (date.getMonth() == currentDate.getMonth()) len = currentDate.getDate()
    date.setDate(len)
  } else if (type == 3) {
    // 判断是否为当年
    if (date.getFullYear() == currentDate.getFullYear()) {
      date.setMonth(currentDate.getMonth())
      date.setDate(currentDate.getDate())
    } else {
      date.setMonth(11)
      date.setDate(getMonthLen(12, date.getFullYear()))
    }
  }

  // 结束时间
  date.setHours(23)
  date.setMinutes(59)
  date.setSeconds(59)
  date.setMilliseconds(999)
  let end = date.getTime()
  return {
    start,
    end
  }
}

// 获取日期下级日时间列表
// 0-日 1-月 2-年
export const getDateSubList = (type: number, tsp: number) => {
  const data: number[] = []
  if (type == 0) {
    let start = getDateOriginAndEnd(tsp).start
    for (let i = 0; i < 24; i++) {
      data.push(start)
      start += TspObj['hour']
    }
  } else if (type == 1) {
    const date = new Date(tsp)
    const days = getMonthLen(date.getMonth() + 1, date.getFullYear())
    let start = getDateOriginAndEnd(tsp, 2).start
    for (let i = 0; i < days; i++) {
      data.push(start)
      start += TspObj['day']
    }
  } else if (type == 2) {
    let start = getDateOriginAndEnd(tsp, 3).start
    for (let i = 0; i < 12; i++) {
      data.push(start)
      const date = new Date(start)
      const mLen = getMonthLen(date.getMonth() + 1, date.getFullYear())
      TspObj.month = mLen * 24 * hour
      start += TspObj['month']
    }
  }
  return data
}

/* '''
message：要加密的消息，可以是字符串或 WordArray 对象。
ciphertext：AES加密密文
key：用于加密的密钥，可以是字符串、WordArray 对象或者一个包含字节的数组。
options（可选）：加密选项，如加密模式、填充方式等。
''' */
import CryptoJS from 'crypto-js'

const encryKey = 'Foxconn;'

// 解密 AES
export const decryptAES = (word: string, keyStr?: string, ivStr?: string) => {
  keyStr = keyStr ? keyStr : encryKey
  ivStr = ivStr ? ivStr : encryKey
  var key = CryptoJS.enc.Utf8.parse(keyStr)
  let iv = CryptoJS.enc.Utf8.parse(ivStr)
  var decrypt = CryptoJS.AES.decrypt(word, key, {
    iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return decrypt.toString(CryptoJS.enc.Utf8)
}
